#ifndef RBFINTERPOLATION_H
#define RBFINTERPOLATION_H

#include<vector>
using namespace std;

namespace rbf_interp {

    /*
      高斯函数
      r：两点之间的距离
    */
    double rbfGaussian(double distance);

    /*
      计算两点之间的欧几里得距离
      firstPointCoord:点firstPointCoord的坐标
      secondPointCoord:点secondPointCoord的坐标
    */
    double euclideanDistance(
        const vector<double>& firstPointCoord,
        const vector<double>& secondPointCoord);

	vector<double> getExtremum(const vector<double>& values);
	/*
	 *	归一化值向量
	 *	@return: 归一化后的值向量
	 */
	vector<double> normalize(const vector<double>& values);
	vector<double> denormalize(const vector<double>& normalized_values, double min_value, double max_value);
	void denormalize(vector<double>& normalized_values, const vector<double>& values);
	// 半方差函数
	double semivariance(double h, double nugget, double sill, double range);
    /*
     矩阵求逆
     matrix：插值矩阵
     inverseMatrix：插值矩阵的逆矩阵，初始时为空
    */
    bool invertMatrix(
        vector<vector<double>>& matrix,
        size_t n,
        vector<vector<double>>& inverseMatrix);

    /*
     向量与矩阵的乘法
     value_vector：值向量
     inverseMatrix：插值矩阵的逆矩阵
    */
    vector<double> vectorMatrixMultiply(
        const vector<double>& valueVector,
        const vector<vector<double>>& inverseMatrix);

    /*
     RBF插值函数
     roofCoood：参考点坐标
     sValues：参考点点对应的应力分量
     targetPoint：目标点坐标
   */
    double rbfInterpolateValue(
        const vector<vector<double>>& roofCoood,
        const vector<double>& sValues,
        const vector<double>& targetPoint);

    /*
     RBF插值函数
     roofCoood：贡献点坐标
     values：贡献点对应的杨氏模量和泊松比
     targetPoint：目标点坐标
    */
    vector<double> rbfInterpolateTwovalues(
        const vector<vector<double>>& roofCoood,
        const vector<vector<double>>& values,
        const vector<double>& targetPoint);

    vector<vector<double>> rbfExtrapolate(
        const vector<vector<double>>& roofCoord,
        const vector<vector<double>>& values,
        const vector<vector<double>>& targetPoints,
        int thread = 1);

    void rbfInterpolate(CPgrid& ori_grid, finiteGrid& ext_grid, int thread_num = 1);

	void ExtrapolateInterpolate(CPgrid& ori_grid, finiteGrid& ext_grid, int thread_num = 1);

	vector<vector<double>> krigingInterpolation(const vector<vector<double>>& roofCoord,
												const vector<vector<double>>& values,
												const vector<vector<double>>& targetPoints_ext,
												int thread);

	 //计算向量叉积
	vector<double> crossProduct(
		const vector<double>& v1,
		const vector<double>& v2);

	//计算向量点积
	double dotProduct(const vector<double>& v1,
			const vector<double>& v2);
	
	//计算四面体体积
	double tetrahedronVolume(const vector<double>& a, 
		const vector<double>& b, 
		const vector<double>& c, 
		const vector<double>& d);

   //计算六面体总体积 
   double hexahedronVolume(const vector<vector<double>>& points);
  

   //计算守恒系数
   /*
     total_volume:六面体网格单元体积
	 total_rockden:六面体网格单元的总密度
	 total_poro: 六面体网格单元的总孔隙度
	 volume：拆分出来的四面体体积
	 reckden: 拆分出来的四面体的密度
	 poro: 拆分出来的四面体孔隙度
   */
	vector<double> calculatedConservationCoefficient(
		double total_volume,
		double total_rockden,
		double total_poro,
		const vector<double>& volume,
		const vector<double>& rockden,
		const vector<double>& poro);

    void assign(finiteGrid& grid, vector<vector<double>>values);


	void Interp(CPgrid& ori_grid, finiteGrid& ext_grid, int thread_num = 1);

}//namespace reb_interp

#endif
